import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { ConfigModule } from "@nestjs/config";
import { DbEntityList } from "@/db/db.service";
import {
  TypeOrmModuleOptions,
  TypeOrmModuleAsyncOptions,
} from "@nestjs/typeorm";
import { CacheModuleOptions, CacheStore } from "@nestjs/cache-manager";
import { redisStore, RedisStore } from "cache-manager-redis-store";
import {
  ServeStaticModuleAsyncOptions,
  ServeStaticModuleOptions,
} from "@nestjs/serve-static";
import * as path from "path";
import IConstants from "@/core/constants";

@Injectable()
export class AppService {}

export function buildTypeormModuleConfig(): TypeOrmModuleAsyncOptions {
  return {
    imports: [ConfigModule],
    inject: [ConfigService],
    useFactory: function typeormFactoryFunc(
      configService: ConfigService,
    ): TypeOrmModuleOptions {
      const baseConfig = {
        entities: [...DbEntityList],
        synchronize: true,
        logging: false,
        // logging: process.env.RUNNING_ENV === 'development'
      };
      const mysqlConfig: TypeOrmModuleOptions = {
        type: "mysql",
        host: configService.get("MYSQL_HOST"), // 数据库ip地址
        port: configService.get("MYSQL_PORT"), // 端口
        username: configService.get("MYSQL_USER"), // 登录名
        password: configService.get("MYSQL_PWD"), // 密码
        database: configService.get("MYSQL_DATABASE"), // 数据库名称
        ...baseConfig,
      };
      const sqliteConfig: TypeOrmModuleOptions = {
        type: "sqlite",
        database: configService.get("SQLITE_DATABASE"),
        ...baseConfig,
      };
      return configService.get("DATABASE_TYPE") === "mysql"
        ? mysqlConfig
        : sqliteConfig;
    },
  };
}

export function buildCacheModuleConfig(): CacheModuleOptions {
  return {
    isGlobal: true,
    imports: [ConfigModule],
    inject: [ConfigService],
    useFactory: async function (configService: ConfigService) {
      const redisUrl: string = configService.get("REDIS_URL", "");
      if (!redisUrl) return {};
      const store: RedisStore = await redisStore({
        url: configService.get("REDIS_URL"),
        ttl: 60 * 1000,
      });
      return {
        store: store as unknown as CacheStore,
      };
    },
  };
}

export function buildServeStaticConfig(): ServeStaticModuleAsyncOptions {
  return {
    isGlobal: true,
    imports: [ConfigModule],
    inject: [ConfigService],
    useFactory: function (
      configService: ConfigService,
    ): ServeStaticModuleOptions[] {
      return [
        {
          rootPath: IConstants.publicDir,
          serveRoot: "/" + configService.get("STATIC_PREFIX", "static"),
        },
      ];
    },
  };
}
